﻿using BCCommon;
using BCCommon.Extensions;
using BCCommon.TMS.Driver;
using BCCommon.TMS.Transport;
using BCData.TMS.Agent.AgentRecord;
using BCData.TMS.Agent.AgnetVehicleType;
using BCData.TMS.FreightConfiguration;
using BCData.TMS.VehicleBusinessMapping;
using BCData.TMS.VehicleCategoryReference;
using BCData.TMS.VehicleTransportBusinessConfig;
using BCData.TMS.VehicleType;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.VehicleBusinessMapping;
using BCDto.TMS.VehicleCategoryReference;
using BCDto.TMS.VehicleType;
using BCDto.TMS.VehicleType.VehicleGroup;
using BCEntity.Common.EntityNameConst;
using BCEntity.TMS.Agent.AgnetVehicleType;
using BCEntity.TMS.FreightConfiguration;
using BCEntity.TMS.VehicleCategoryReference;
using BCEntity.TMS.VehicleType;
using BCService.Common.Dictionary;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.TMS.VehicleTypeService
{
    public class VehicleTypeService : IVehicleTypeService
    {
        #region 私有变量

        private readonly IRedisService redisService;
        private readonly IVehicleTypeData vehicleTypeData;
        private readonly IDictionaryReferenceService dictionaryService;
        private readonly IVehicleCategoryReferenceData vehicleCategoryReferenceData;
        private readonly IFreightConfigurationData freightConfigurationData;
        private readonly IAgentRecordData agentRecordData;
        private readonly IAgentVehicleTypeData agnetVehicleTypeData;
        private readonly IDatabaseContext databaseContext;
        private readonly IVehicleTransportBusinessConfigOverwriteData vehicleTransportBusinessConfigOverwriteData;
        private readonly IVehicleBusinessMappingOverwriteData vehicleBusinessMappingOverwriteData;
        private readonly string categoryReferenceKey = string.Format("{0}", EntityNameConst.VehicleCategoryReferenceExpandEntity);
        private readonly string vehcleTypeExpandkey = string.Format("{0}", EntityNameConst.VehicleTypeExpandEntity);

        #endregion 私有变量

        #region 构造函数

        public VehicleTypeService(
            IRedisService redisService,
            IVehicleTypeData vehicleTypeData,
            IDictionaryReferenceService dictionaryService,
            IFreightConfigurationData freightConfigurationData,
            IVehicleCategoryReferenceData vehicleCategoryReferenceData,
            IAgentRecordData agentRecordData,
            IAgentVehicleTypeData agnetVehicleTypeData,
            IDatabaseContext databaseContext,
            IVehicleTransportBusinessConfigOverwriteData vehicleTransportBusinessConfigOverwriteData,
            IVehicleBusinessMappingOverwriteData vehicleBusinessMappingOverwriteData)
        {
            this.redisService = redisService;
            this.vehicleTypeData = vehicleTypeData;
            this.dictionaryService = dictionaryService;
            this.vehicleCategoryReferenceData = vehicleCategoryReferenceData;
            this.freightConfigurationData = freightConfigurationData;
            this.agentRecordData = agentRecordData;
            this.agnetVehicleTypeData = agnetVehicleTypeData;
            this.databaseContext = databaseContext;
            this.vehicleTransportBusinessConfigOverwriteData = vehicleTransportBusinessConfigOverwriteData;
            this.vehicleBusinessMappingOverwriteData = vehicleBusinessMappingOverwriteData;
        }

        #endregion 构造函数

        #region 车辆类型

        public VehicleTypeDto Add(AdminDto admin, VehicleTypeRequestDto dto)
        {
            //1 检查检索键是否存在于字典中
            var dictionary = dictionaryService.GetBySearchkeyAsync(dto.VehicleTypeEnum).Result;
            if (dictionary.Count == 0)
                throw new ArgumentException($"检索键{dto.VehicleTypeEnum} 在字典中不存在 ");
            if (dictionary.Any(s => s.SearchKey == "VehicleTypeEnum_Electric_MaterialConfiguration" && s.SearchKey != "VehicleTypeEnum_Motorcycle_MaterialConfiguration"))
                dto.VehicleTypeName = dictionary.First().ItemValue;
            else
            {
                dto.VehicleTypeName = $"{dto.VehicleLength}米";
            }
            //2 通过车型名称和所属类型检查车型是否已存在
            var vehicleTypeList = this.vehicleTypeData.GetAsync(dto.VehicleTypeName, dto.VehicleTypeEnum).Result;
            if (vehicleTypeList.Any(p => p.VehicleTypeName == dto.VehicleTypeName.Trim()))
            {
                throw new ArgumentException("车型名称已存在，请更换其他车型名称");
            }
            var entity = dto.As<VehicleTypeEntity>();
            entity.Editer = admin.FullName;
            //3 获取车型图片
            string host = GeneralContainer.Configuration["CurrentlyImageHost"];
            var img = vehicleTypeData.GetVehicleTypeImg(dto.VehicleTypeEnum).Result;
            if (!string.IsNullOrWhiteSpace(img))
            {
                entity.VehiclePicPath = string.Format("{0}{1}", host, img);
            }
            else
            {
                if (string.IsNullOrWhiteSpace(dto.VehiclePicPath))
                {
                    entity.VehiclePicPath = dto.VehiclePicPath;
                }
            }
            this.databaseContext.BeginTransaction();
            var vehicleCategoryReferences = dto.VehicleCategory.Select(x =>
            {
                var parameter = new VehicleCategoryReferenceEntity() { VehicleCategory = x };
                return parameter;
            }).ToList();
            var result = vehicleTypeData.InserAsync(entity, vehicleCategoryReferences).GetAwaiter().GetResult();
            if (result == null)
            {
                throw new ArgumentException("创建车辆类型失败");
            }
            this.databaseContext.Commit();
            this.redisService.DeleteMultipleKey(string.Format("{0}", EntityNameConst.VehicleTypeEntity), false);
            return result.As<VehicleTypeDto>();
        }


        public (int vehicleTypeId, int vehicleCategoryReferenceId) AuditVehicleInsertAsync(VehicleTypeRequestDto dto)
        {
            // 新增车辆类型
            var newId = InsertVehicleType(dto);
            if (newId > 0)
            {
                if (dto.VehicleCategory.Count > 0)
                {
                    var res = vehicleCategoryReferenceData.SingleInsertAsync(new VehicleCategoryReferenceEntity()
                    {
                        VehicleCategory = dto.VehicleCategory.First(),
                        VehicleTypeId = newId
                    }).GetAwaiter().GetResult();
                    if (res > 0) return (newId, res);

                    //1.2 如果创建关系失败，删除前面已经新增的车型
                    vehicleTypeData.DeleteAsync(newId).GetAwaiter().GetResult();
                }
            }
            throw new ArgumentException("创建车辆类型失败");
        }

        public VehicleTypeDto Update(AdminDto admin, int vehicleTypeId, VehicleTypeRequestDto dto)
        {
            if (vehicleTypeId == 0)
            {
                throw new ArgumentException("参数 VehicleTypeId 不能为 0");
            }
            string host = GeneralContainer.Configuration["CurrentlyImageHost"];
            //1 检查修改车辆类型是否存在
            CheckVehicleType(vehicleTypeId);
            // 检查修改车型名称是否已存在
            var vehicleTypeList = this.vehicleTypeData.GetAsync(dto.VehicleTypeName, dto.VehicleTypeEnum).Result;
            if (vehicleTypeList.Any(p => p.VehicleTypeId != vehicleTypeId && p.VehicleTypeName == dto.VehicleTypeName.Trim()))
            {
                throw new ArgumentException("车型名称已存在，请更换其他车型名称");
            }
            //2 检查检索键是否存在于字典中
            var dictionary = dictionaryService.GetBySearchkeyAsync(dto.VehicleTypeEnum).Result;
            if (dictionary.Count == 0)
                throw new ArgumentException($"检索键{dto.VehicleTypeEnum} 在字典中不存在 ");
            if (dictionary.Any(s => s.SearchKey == "VehicleTypeEnum_Electric_MaterialConfiguration" && s.SearchKey != "VehicleTypeEnum_Motorcycle_MaterialConfiguration"))
                dto.VehicleTypeName = dictionary.First().ItemValue;
            else
            {
                dto.VehicleTypeName = $"{dto.VehicleLength}米";
            }
            var entity = dto.As<VehicleTypeEntity>();
            entity.VehicleTypeId = vehicleTypeId;
            entity.Editer = admin.FullName;
            //3 获取车型图片
            var img = vehicleTypeData.GetVehicleTypeImg(dto.VehicleTypeEnum).Result;
            if (!string.IsNullOrWhiteSpace(img))
            {
                entity.VehiclePicPath = string.Format("{0}{1}", host, img);
            }
            else
            {
                if (string.IsNullOrWhiteSpace(dto.VehiclePicPath))
                {
                    entity.VehiclePicPath = dto.VehiclePicPath;
                }
            }
            //4 修改车辆类型信息
            this.databaseContext.BeginTransaction();
            var vehicleCategoryReferences = dto.VehicleCategory.Select(x =>
            {
                var parameter = new VehicleCategoryReferenceEntity() { VehicleTypeId = vehicleTypeId, VehicleCategory = x };
                return parameter;
            }).ToList();
            var result = vehicleTypeData.UpdateAsync(entity, vehicleCategoryReferences).Result;
            if (result == null)
            {
                throw new ArgumentException("修改车辆类型失败");
            }
            this.databaseContext.Commit();
            this.redisService.DeleteMultipleKey(string.Format("{0}", EntityNameConst.VehicleTypeEntity), false);
            return result.As<VehicleTypeDto>();
        }

        public bool UpdateAuditStatus(AdminDto admin, int vehicleTypeId, AuditStatusRequestDto auditStatusRequestDto)
        {
            //1、检查修改车辆类型是否存在
            CheckVehicleType(vehicleTypeId);
            databaseContext.BeginTransaction();
            //2、修改车辆类型状态
            if (admin.AgentRecord != null)
            {
                //如果只是代理商修改车型不启用，则只修改代理商车型为不启用
                var agentVehicleType = this.agnetVehicleTypeData.GetById(admin.AgentRecord.AgentRecordId, vehicleTypeId).Result;
                if (agentVehicleType != null)
                {
                    agentVehicleType.Enabled = auditStatusRequestDto.IsEnabled;
                    agentVehicleType.UpdateTime = DateTime.Now;
                    this.agnetVehicleTypeData.UpdateAsync(agentVehicleType).GetAwaiter().GetResult();
                }
                else
                {
                    this.agnetVehicleTypeData.InsertAsync(new AgentVehicleTypeEntity()
                    {
                        AgentRecordId = admin.AgentRecord.AgentRecordId,
                        VehicleTypeId = vehicleTypeId,
                        Enabled = auditStatusRequestDto.IsEnabled,
                        CreateTime = DateTime.Now,
                        UpdateTime = DateTime.Now
                    }).GetAwaiter().GetResult();
                }
            }
            else
            {
                //如果是总部修改车型启用状态为不启用，则连带着将代理商车型也修改为不启用状态
                vehicleTypeData.UpdateAsync(vehicleTypeId, auditStatusRequestDto.IsEnabled).GetAwaiter().GetResult();
                if (!auditStatusRequestDto.IsEnabled)
                {
                    this.agnetVehicleTypeData.UpdateEnabledByVehicleTypeId(vehicleTypeId).GetAwaiter().GetResult();
                }
            }
            databaseContext.Commit();
            //if (res > 0) return res;
            this.redisService.DeleteMultipleKey(string.Format("{0}", EntityNameConst.VehicleTypeEntity), false);
            return true; ;
        }

        public VehicleTypeDto GetById(int vehicleTypeId)
        {
            //1 读取车辆类型信息
            var vehicleInfo = this.redisService.TryGet(string.Format("{0}:NewGet:VehicleTypeId={1}", EntityNameConst.VehicleTypeEntity, vehicleTypeId), () =>
            {
                var vehicleInfoTask = vehicleTypeData.GetByIdAsync(vehicleTypeId);
                var data = vehicleInfoTask.GetAwaiter().GetResult();
                return data.As<VehicleTypeDto>();
            }, TimeSpan.FromDays(1));

            //2 读取车辆所属分类列表
            var vehicleCategoryList = this.redisService.TryGet(
                $"{EntityNameConst.VehicleCategoryReferenceEntity}:VehicleTypeId={vehicleTypeId}", () =>
            {
                var vehicleCategoryListTask = vehicleCategoryReferenceData.GetByVehicleTypeId(vehicleTypeId);
                var data = vehicleCategoryListTask.GetAwaiter().GetResult();
                return data.As<List<VehicleCategoryReferenceDto>>();
            }, TimeSpan.FromDays(1));

            vehicleInfo.VehicleSubCategoryList = vehicleCategoryList;
            return vehicleInfo;
        }

        public List<VehicleTypeDto> VehicleNameList()
        {
            var data = this.redisService.TryGet(string.Format("{0}:VehicleNameList", EntityNameConst.VehicleTypeEntity), () =>
             {
                 var task = vehicleTypeData.GetAsync(string.Empty, string.Empty);
                 var result = task.GetAwaiter().GetResult();
                 return result.As<IEnumerable<VehicleTypeDto>>();
             }, TimeSpan.FromDays(1));
            return data.ToList();
        }

        public PageableList<VehicleTypeDto> PageWhereList(AdminDto admin, string categoryReferenceIdStr, int? vehicleTypeId, string vehicleTypeEnum, int? maxStartWeight, int? maxEndWeight, decimal? maxStartStere, decimal? maxEndStere, bool? enabled, int pageIndex, int pageSize)
        {
            if (admin.AgentRecord == null)
            {
                var cacheKey = this.redisService.GetKey(vehcleTypeExpandkey, categoryReferenceIdStr, vehicleTypeId, vehicleTypeEnum, maxStartWeight, maxEndWeight,
                    maxStartStere, maxEndStere, enabled, pageIndex, pageSize);
                var result = this.redisService.TryGet(cacheKey, () =>
                {
                    var (data, dataCount) = vehicleTypeData.GetAsync(categoryReferenceIdStr, vehicleTypeId, vehicleTypeEnum, maxStartWeight, maxEndWeight,
                    maxStartStere, maxEndStere, enabled, pageIndex, pageSize).Result;
                    var list = data.As<List<VehicleTypeDto>>();
                    var vehicleCategoryList = this.redisService.TryGet(categoryReferenceKey, () =>
                    {
                        var vehicleCategory = vehicleCategoryReferenceData.GetByVehicleTypeId().Result;
                        return vehicleCategory;
                    }, TimeSpan.FromDays(30));
                    foreach (var item in list)
                    {
                        item.VehicleSubCategoryList = vehicleCategoryList.Where(x => x.VehicleTypeId == item.VehicleTypeId).As<List<VehicleCategoryReferenceDto>>();
                    }
                    return new PageableList<VehicleTypeDto>()
                    {
                        Count = dataCount,
                        Items = list,
                        PageIndex = pageIndex,
                        PageSize = pageSize
                    };
                }, TimeSpan.FromDays(30));
                return result;
            }
            else
            {
                var cacheKey = this.redisService.GetKey(vehcleTypeExpandkey, admin.AgentRecord?.AgentRecordId, categoryReferenceIdStr, vehicleTypeId, vehicleTypeEnum, maxStartWeight, maxEndWeight,
                       maxStartStere, maxEndStere, enabled, pageIndex, pageSize);
                var result = this.redisService.TryGet(cacheKey, () =>
                {
                    var (data, dataCount) = this.agnetVehicleTypeData.GetAsync(admin.AgentRecord?.AgentRecordId, categoryReferenceIdStr, vehicleTypeId, vehicleTypeEnum, maxStartWeight, maxEndWeight,
                        maxStartStere, maxEndStere, enabled, pageIndex, pageSize).Result;
                    var list = data.As<List<VehicleTypeDto>>();
                    var vehicleCategoryList = this.redisService.TryGet(categoryReferenceKey, () =>
                    {
                        var vehicleCategory = vehicleCategoryReferenceData.GetByVehicleTypeId().Result;
                        return vehicleCategory;
                    }, TimeSpan.FromDays(30));
                    foreach (var item in list)
                    {
                        item.VehicleSubCategoryList = vehicleCategoryList.Where(x => x.VehicleTypeId == item.VehicleTypeId).As<List<VehicleCategoryReferenceDto>>();
                    }
                    return new PageableList<VehicleTypeDto>()
                    {
                        Count = dataCount,
                        Items = list,
                        PageIndex = pageIndex,
                        PageSize = pageSize
                    };
                }, TimeSpan.FromDays(30));
                return result;
            }
        }


        public MaxVehicleTypeValueDto MaxVehicleTypeValue()
        {
            var result = this.vehicleTypeData.MaxVehicleTypeValue().GetAwaiter().GetResult();
            return result.As<MaxVehicleTypeValueDto>();
        }


        #region 车辆分类对应表

        public List<VehicleCategoryReferenceDto> GetCategoryReferenceList(int? vehicleTypeId)
        {
            string cacheKey = this.redisService.GetKey(categoryReferenceKey, vehicleTypeId);
            var result = this.redisService.TryGet(cacheKey, () =>
             {
                 var data = vehicleCategoryReferenceData.GetCategoryReferenceList(vehicleTypeId).Result;
                 return data;
             });
            return result.As<List<VehicleCategoryReferenceDto>>();
        }

        #endregion 车辆分类对应表

        #endregion 车辆类型

        #region 私有方法

        /// <summary>
        /// 检查车辆是否存在
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private void CheckVehicleType(int id)
        {
            var vehicelInfo = vehicleTypeData.GetByIdAsync(id).Result;
            if (vehicelInfo == null)
                throw new ArgumentException("车型不存在");
        }

        /// <summary>
        /// 新增车辆类型
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        private int InsertVehicleType(VehicleTypeRequestDto dto)
        {
            ////1 通过车型名称和所属类型检查车型是否已存在
            //var list = vehicleTypeData.GetAsync(vehicleTypeName: dto.VehicleTypeName, vehicleTypeEnum: dto.VehicleTypeEnum).Result;
            //if (list.Any())
            //    throw new ArgumentException("车型已存在");
            //1 通过车型名称检查车型是否已存在
            var vehicleTypeEntity = this.vehicleTypeData.GetByVehicleTypeName(dto.VehicleTypeName).Result;
            if (vehicleTypeEntity != null)
            {
                throw new ArgumentException("车型已存在");
            }
            //2 检查检索键是否存在于字典中
            var dictionary = dictionaryService.GetBySearchkeyAsync(dto.VehicleTypeEnum).Result;
            if (dictionary.Count == 0)
                throw new ArgumentException($"检索键{dto.VehicleTypeEnum} 在字典中不存在 ");
            var entity = dto.As<VehicleTypeEntity>();
            //3 获取车型图片
            var img = vehicleTypeData.GetVehicleTypeImg(dto.VehicleTypeEnum).Result;
            if (!string.IsNullOrWhiteSpace(img))
            {
                entity.VehiclePicPath = img;
            }
            //var newId = vehicleTypeData.InserAsync(entity).GetAwaiter().GetResult();
            //return newId;

            var result = vehicleTypeData.InserAsync(entity).GetAwaiter().GetResult();
            this.redisService.DeleteMultipleKey(string.Format("{0}", EntityNameConst.VehicleTypeEntity), false);
            return result == null ? 0 : result.VehicleTypeId;
        }

        #endregion 私有方法

        #region AppClient使用

        public List<VehicleGroupDto> GetVehicleTypes(string provinceCode, string cityCode, string countyCode)
        {
            if (string.IsNullOrWhiteSpace(provinceCode) || provinceCode.Length != 6)
            {
                throw new ArgumentException("省份编码错误");
            }
            if (string.IsNullOrWhiteSpace(cityCode) || cityCode.Length != 6)
            {
                throw new ArgumentException("城市编码错误");
            }
            if (string.IsNullOrWhiteSpace(countyCode) || countyCode.Length != 6)
            {
                throw new ArgumentException("区县编码错误");
            }
            string key = string.Format("{0}:GetVehicleTypes:ProvinceCode={1}:CityCode={2}:CountyCode={3}", EntityNameConst.VehicleTypeEntity, provinceCode, cityCode, countyCode);
            FreightConfigurationViewEntity freightConfigurationViewEntity = new FreightConfigurationViewEntity
            {
                ProvinceCode = provinceCode,
                CityCode = cityCode,
                CountyCode = countyCode,
                PageIndex = 0,
                PageSize = 10000
            };
            var result = this.redisService.TryGet(key, () =>
            {
                IEnumerable<VehicleTypeExpandEntity> list = this.vehicleTypeData.GetVehicleTypes().Result;
                var listResult = list.As<IEnumerable<VehicleTypeFreightDto>>();

                foreach (var item in listResult)
                {
                    freightConfigurationViewEntity.VehicleTypeId = item.VehicleTypeId;
                    //Task<IEnumerable<VehicleCategoryReferenceExpandEntity>> categoryList = this.vehicleCategoryReferenceData.GetVehicleCategoryReferenceExpandEntity(item.VehicleTypeId);
                    //Task<(IEnumerable<FreightConfigurationExpandEntity>, int dataCount)> freightConfigurationExpandEntitiesTask = this.freightConfigurationData.QeuryAsync(freightConfigurationViewEntity);
                    //(IEnumerable<FreightConfigurationExpandEntity>, int dataCount) freightConfigurationExpandEntitiesResult = freightConfigurationExpandEntitiesTask.GetAwaiter().GetResult();
                    //IEnumerable<FreightConfigurationExpandEntity> freightConfigurationExpandEntities = freightConfigurationExpandEntitiesResult.Item1;

                    IEnumerable<VehicleCategoryReferenceExpandEntity> categoryList = this.vehicleCategoryReferenceData.GetVehicleCategoryReferenceExpandEntity(item.VehicleTypeId).Result;
                    var (data, dataCount) = this.freightConfigurationData.QeuryAsync(freightConfigurationViewEntity).Result;
                    IEnumerable<FreightConfigurationExpandEntity> freightConfigurationExpandEntities = data;
                    if (freightConfigurationExpandEntities.Any())
                    {
                        decimal minStartPrice = freightConfigurationExpandEntities.Min(p => p.StartPrice);
                        decimal maxStartPrice = freightConfigurationExpandEntities.Max(p => p.StartPrice);
                        decimal minMileagePrice = freightConfigurationExpandEntities.Min(p => p.MileagePrice);
                        decimal maxMileagePrice = freightConfigurationExpandEntities.Max(p => p.MileagePrice);
                        if (minStartPrice == maxStartPrice)
                        {
                            item.RangeStartPrice = minStartPrice.ToString();
                        }
                        else
                        {
                            item.RangeStartPrice = string.Format("{0}-{1}", minStartPrice, maxStartPrice);
                        }
                        if (minMileagePrice == maxMileagePrice)
                        {
                            item.RangeMileagePrice = minMileagePrice.ToString();
                        }
                        else
                        {
                            item.RangeMileagePrice = string.Format("{0}-{1}", minMileagePrice, maxMileagePrice);
                        }
                    }

                    List<VehicleCategoryReferenceFreightDto> vehicleCategoryReferenceDtos = categoryList.As<List<VehicleCategoryReferenceFreightDto>>();

                    foreach (var dto in vehicleCategoryReferenceDtos)
                    {
                        FreightConfigurationExpandEntity freightConfigurationExpandEntity = freightConfigurationExpandEntities.SingleOrDefault(p => p.VehicleCategoryReferenceId == dto.VehicleCategoryReferenceId);
                        if (freightConfigurationExpandEntity != default(FreightConfigurationExpandEntity))
                        {
                            dto.StartPrice = freightConfigurationExpandEntity.StartPrice;
                            dto.StartMileage = freightConfigurationExpandEntity.StartMileage;
                            dto.MileagePrice = freightConfigurationExpandEntity.MileagePrice;
                        }
                    }
                    item.VehicleSubCategoryList = vehicleCategoryReferenceDtos;
                }
                List<VehicleGroupDto> vehicleGroups = new List<VehicleGroupDto>();
                foreach (string item in listResult.Select(p => p.VehicleTypeValue).Distinct())
                {
                    VehicleGroupDto vehicleGroupDto = new VehicleGroupDto
                    {
                        VehicleType = item,
                        VehiclePicPath = listResult.FirstOrDefault(p => p.VehicleTypeValue == item).VehiclePicPath,
                        VehicleTypeList = listResult.Where(p => p.VehicleTypeValue == item).OrderBy(p => p.VehicleLength)
                    };
                    if (!vehicleGroupDto.VehiclePicPath.Contains("http://") && !vehicleGroupDto.VehiclePicPath.Contains("https://"))
                    {
                        vehicleGroupDto.VehiclePicPath = GeneralContainer.Configuration["DefaultHost"] + vehicleGroupDto.VehiclePicPath;
                    }
                    vehicleGroups.Add(vehicleGroupDto);
                }
                return vehicleGroups;
            }, TimeSpan.FromMinutes(30));
            return result;
        }

        public IEnumerable<VehicleTypeFreightDto> GetVehicleTypesQuery(string provinceCode, string cityCode, string countyCode)
        {
            if (string.IsNullOrWhiteSpace(provinceCode) || provinceCode.Length != 6)
            {
                throw new ArgumentException("省份编码错误");
            }
            if (string.IsNullOrWhiteSpace(cityCode) || cityCode.Length != 6)
            {
                throw new ArgumentException("城市编码错误");
            }
            if (string.IsNullOrWhiteSpace(countyCode) || countyCode.Length != 6)
            {
                throw new ArgumentException("区县编码错误");
            }
            string key = string.Format("{0}:GetVehicleTypesQuery:ProvinceCode={1}:CityCode={2}:CountyCode={3}", EntityNameConst.VehicleTypeEntity, provinceCode, cityCode, countyCode);
            FreightConfigurationViewEntity freightConfigurationViewEntity = new FreightConfigurationViewEntity
            {
                ProvinceCode = provinceCode,
                CityCode = cityCode,
                CountyCode = countyCode,
                PageIndex = 0,
                PageSize = 10000
            };
            var result = this.redisService.TryGet(key, () =>
            {
                IEnumerable<VehicleTypeExpandEntity> list = this.vehicleTypeData.GetVehicleTypes().Result;
                //var listResult = list.GetAwaiter().GetResult().As<IEnumerable<VehicleTypeFreightDto>>();
                var listResult = list.As<IEnumerable<VehicleTypeFreightDto>>();

                foreach (var item in listResult)
                {
                    freightConfigurationViewEntity.VehicleTypeId = item.VehicleTypeId;
                    //Task<IEnumerable<VehicleCategoryReferenceExpandEntity>> categoryList = this.vehicleCategoryReferenceData.GetVehicleCategoryReferenceExpandEntity(item.VehicleTypeId);
                    //Task<(IEnumerable<FreightConfigurationExpandEntity>, int dataCount)> freightConfigurationExpandEntitiesTask = this.freightConfigurationData.QeuryAsync(freightConfigurationViewEntity);
                    //(IEnumerable<FreightConfigurationExpandEntity>, int dataCount) freightConfigurationExpandEntitiesResult = freightConfigurationExpandEntitiesTask.GetAwaiter().GetResult();
                    //IEnumerable<FreightConfigurationExpandEntity> freightConfigurationExpandEntities = freightConfigurationExpandEntitiesResult.Item1;

                    IEnumerable<VehicleCategoryReferenceExpandEntity> categoryList = this.vehicleCategoryReferenceData.GetVehicleCategoryReferenceExpandEntity(item.VehicleTypeId).Result;
                    var (data, dataCount) = this.freightConfigurationData.QeuryAsync(freightConfigurationViewEntity).Result;
                    IEnumerable<FreightConfigurationExpandEntity> freightConfigurationExpandEntities = data;
                    if (freightConfigurationExpandEntities.Any())
                    {
                        decimal minStartPrice = freightConfigurationExpandEntities.Min(p => p.StartPrice);
                        decimal maxStartPrice = freightConfigurationExpandEntities.Max(p => p.StartPrice);
                        decimal minMileagePrice = freightConfigurationExpandEntities.Min(p => p.MileagePrice);
                        decimal maxMileagePrice = freightConfigurationExpandEntities.Max(p => p.MileagePrice);
                        if (minStartPrice == maxStartPrice)
                        {
                            item.RangeStartPrice = minStartPrice.ToString();
                        }
                        else
                        {
                            item.RangeStartPrice = string.Format("{0}-{1}", minStartPrice, maxStartPrice);
                        }
                        if (minMileagePrice == maxMileagePrice)
                        {
                            item.RangeMileagePrice = minMileagePrice.ToString();
                        }
                        else
                        {
                            item.RangeMileagePrice = string.Format("{0}-{1}", minMileagePrice, maxMileagePrice);
                        }
                    }

                    List<VehicleCategoryReferenceFreightDto> vehicleCategoryReferenceDtos = categoryList.As<List<VehicleCategoryReferenceFreightDto>>();

                    foreach (var dto in vehicleCategoryReferenceDtos)
                    {
                        FreightConfigurationExpandEntity freightConfigurationExpandEntity = freightConfigurationExpandEntities.SingleOrDefault(p => p.VehicleCategoryReferenceId == dto.VehicleCategoryReferenceId);
                        if (freightConfigurationExpandEntity != default(FreightConfigurationExpandEntity))
                        {
                            dto.StartPrice = freightConfigurationExpandEntity.StartPrice;
                            dto.StartMileage = freightConfigurationExpandEntity.StartMileage;
                            dto.MileagePrice = freightConfigurationExpandEntity.MileagePrice;
                        }
                    }
                    item.VehicleSubCategoryList = vehicleCategoryReferenceDtos;
                }
                return listResult;
            }, TimeSpan.FromMinutes(30));
            return result;
        }



        #endregion AppClient使用

        #region 通过长宽高获取车型列表
        public IEnumerable<VehicleTypeDto> GetVehicleList(decimal length, decimal width, decimal height)
        {
            var data = this.redisService.TryGet(string.Format("{0}:GetVehicleList:Length={1}:Width={2}:Height={3}", EntityNameConst.VehicleTypeEntity, length, width, height), () =>
               {
                   var vehicleTypeList = this.vehicleTypeData.GetList().GetAwaiter().GetResult();
                   return vehicleTypeList.Where(p => p.Enabled && (p.VehicleLength + p.VehicleLengthRatio) > length && (p.VehicleWidth + p.VehicleWidthRatio) > width && (p.VehicleHeight + p.VehicleHeightRatio) > height).OrderBy(p => p.MaxWeight);

               }, TimeSpan.FromDays(1));
            return data.As<IEnumerable<VehicleTypeDto>>();
        }
        #endregion

        public IEnumerable<VehicleBusinessMappingViewDto> GetList(long? agentRecordId, string countyCode, TransportBusinessType? transportBusinessType)
        {
            if (string.IsNullOrWhiteSpace(countyCode))
            {
                throw new ArgumentException("区县不能为空");
            }
            var cacheKey = this.redisService.GetKey(vehcleTypeExpandkey, countyCode, transportBusinessType);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var vehicleTransportBusinessConfigOverwrite = this.vehicleTransportBusinessConfigOverwriteData.GetList(agentRecordId, countyCode, transportBusinessType).Result;
                if (vehicleTransportBusinessConfigOverwrite == null)
                {
                    throw new ArgumentException(string.Format("此区域未开通{0}业务", transportBusinessType.HasValue ? transportBusinessType.Value.GetDescriptionString() : string.Empty));
                }
                var vehicleBusinessMappingOverwrite = vehicleBusinessMappingOverwriteData.GetList(agentRecordId, countyCode, vehicleTransportBusinessConfigOverwrite.VehicleTransportBusinessConfigId).Result;
               
                List<VehicleBusinessMappingViewDto> list = vehicleBusinessMappingOverwrite.As<List<VehicleBusinessMappingViewDto>>();
                foreach(var item in list)
                {
                    var vehicleTypeEntity = this.vehicleTypeData.GetByIdAsync(item.VehicleTypeId).Result;
                    item.VehiclePicPath = vehicleTypeEntity.VehiclePicPath;
                    item.AppliedTo = (DriverRoleType)Enum.Parse(typeof(DriverRoleType), vehicleTypeEntity.AppliedTo);
                    item.VehicleLength = vehicleTypeEntity.VehicleLength;
                    item.VehicleWidth = vehicleTypeEntity.VehicleWidth;
                    item.VehicleHeight = vehicleTypeEntity.VehicleHeight;
                    item.MaxWeight = vehicleTypeEntity.MaxWeight;
                    item.MaxStere = vehicleTypeEntity.MaxStere;
                }
                return list.OrderBy(p => p.VehicleLength);
            }, TimeSpan.FromDays(1));
            return result;
        }
    }
}